package com.sensetime.sample.common;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

import com.sensetime.library.finance.common.app.CameraActivity;
import com.sensetime.library.finance.common.type.ResultCode;
import com.sensetime.library.finance.common.type.Size;
import com.sensetime.library.finance.common.util.FileUtil;
import com.sensetime.library.finance.ocr.card.BankCardApi;
import com.sensetime.library.finance.ocr.card.BankCardInfo;
import com.sensetime.library.finance.ocr.card.OnBankCardScanListener;

import java.io.File;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created on 2016/11/23 15:55.
 *
 * @author Han Xu
 */
public class BankCardActivity extends CameraActivity {

    public static final String EXTRA_CARD_ORIENTATION = "extra_card_orientation";
    public static final String EXTRA_CARD_NUMBER = "extra_card_number";
    public static final String EXTRA_BANK_NAME = "extra_bank_name";
    public static final String EXTRA_BANK_ID = "extra_bank_id";
    public static final String EXTRA_CARD_NAME = "extra_card_name";
    public static final String EXTRA_CARD_TYPE = "extra_card_type";

    public static final int BANKCARD = 0x71;
    public static final int CREDITCARD = 0x72;
    private int comeFrom;

    public static final int CARD_ORIENTATION_VERTICAL = 1;
    public static final int CARD_ORIENTATION_HORIZONTAL = 2;

    private static final String FILES_PATH = Environment.getExternalStorageDirectory().getPath() + "/sensetime/";
    private static final String MODEL_FILE_NAME = "M_Bankcard_Mobile_2.6.model";
    private static final String LICENSE_FILE_NAME = "SenseID_OCR.lic";

    //    #Set your API Key & Secret here.
    private static final String API_KEY = "eb9eeb9198674422b19cd4bbeae2faab";
    private static final String API_SECRET = "b34cbc59e1084085a29e652e8ed9f505";

    private boolean mIsVertical = false;
    private boolean mIsStopped = true;

    private ExecutorService mExecutor = null;

    private View mLoadingView = null;

    private OverlayView mOverlayView = null;

    private OnBankCardScanListener mListener = new OnBankCardScanListener() {
        @Override
        public void onError(ResultCode resultCode) {
            setResult(convertResultCode(resultCode));
            finish();
        }

        @Override
        public void onSuccess(BankCardInfo bankCardInfo) {
            Intent intent = new Intent();
            intent.putExtra(EXTRA_CARD_NUMBER, bankCardInfo.getCardNumber());
            intent.putExtra(EXTRA_BANK_NAME, bankCardInfo.getBankName());
            intent.putExtra(EXTRA_BANK_ID, bankCardInfo.getBankId());
            intent.putExtra(EXTRA_CARD_NAME, bankCardInfo.getCardName());
            intent.putExtra(EXTRA_CARD_TYPE, bankCardInfo.getCardType());
            intent.putExtra(EXTRA_CARD_ORIENTATION, mIsVertical ? CARD_ORIENTATION_VERTICAL : CARD_ORIENTATION_HORIZONTAL);
            int[] image = bankCardInfo.getImageData();
            ImageHolder.sImageData = Arrays.copyOf(image, image.length);

            switch (comeFrom) {
                case BANKCARD:
                    setResult(0x73, intent);
                    break;
                case CREDITCARD:
                    setResult(0x74, intent);
                    break;
            }
            finish();
        }

        @Override
        public void onOnlineCheckBegin() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mLoadingView.setVisibility(View.VISIBLE);
                }
            });
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!checkPermission(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            setResult(RESULT_CODE_NO_PERMISSIONS);
            finish();
            return;
        }

        setContentView(R.layout.activity_bankcard);

        findViewById(R.id.img_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

        int cardOrientation = getIntent().getIntExtra(EXTRA_CARD_ORIENTATION, CARD_ORIENTATION_HORIZONTAL);
        comeFrom = getIntent().getIntExtra("whereToUpload", -1);
        Log.d("BankCardActivity", "comeFrom:" + comeFrom);
        mIsVertical = cardOrientation == CARD_ORIENTATION_VERTICAL;
        mOverlayView = ((OverlayView) findViewById(R.id.overlay));
        mOverlayView.setIsVerticalCard(mIsVertical);
        mLoadingView = findViewById(R.id.pb_loading);

        initCameraView(R.id.camera_preview, false, null, getScreenSize());

        File dir = new File(FILES_PATH);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        FileUtil.copyAssetsToFile(getApplicationContext(), MODEL_FILE_NAME, FILES_PATH + MODEL_FILE_NAME);
        FileUtil.copyAssetsToFile(getApplicationContext(), LICENSE_FILE_NAME, FILES_PATH + LICENSE_FILE_NAME);
        ResultCode result = BankCardApi.init(FILES_PATH + LICENSE_FILE_NAME, FILES_PATH + MODEL_FILE_NAME, API_KEY, API_SECRET, mListener);
        if (result != ResultCode.OK) {
            setResult(convertResultCode(result));
            finish();
        }
        startDetectThread();
    }

    @Override
    protected void onPause() {
        mIsStopped = true;
        BankCardApi.cancel();
        destroyExecutor();
        mLoadingView.setVisibility(View.GONE);
        setResult(RESULT_CANCELED);
        finish();
        super.onPause();
    }

    private void startDetectThread() {
        mExecutor = Executors.newSingleThreadExecutor();
        mExecutor.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (mIsStopped) {
                        break;
                    }

                    byte[] imageData = getPreviewData();
                    if (imageData == null) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }

                    BankCardApi.inputScanImage(imageData,
                            getPreviewSize(),
                            mOverlayView.getCardRect(),
                            mIsVertical,
                            getCameraOrientation(),
                            getScreenSize());

                    if (mIsStopped) {
                        break;
                    }
                }
            }
        });
        mIsStopped = false;
    }

    private void destroyExecutor() {
        if (mExecutor == null) {
            return;
        }
        mExecutor.shutdown();
        try {
            mExecutor.awaitTermination(100, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mExecutor = null;
    }

    private Size getScreenSize() {
        WindowManager manager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        return new Size(display.getWidth(), display.getHeight());
    }
}